<!--
使用注意: MyTable的父元素一定要设置width,height, 不然scroll-view滚动后会超出MyTable区域
<view class="pd-xxl" style="width: 100%; height: 100%;"> 
	<MyTable :columns="columns" :rows="rows" :headerStyle="headerStyle" :bodyStyle="bodyStyle"></MyTable>
</view> 
如果要使表格占满整个页面，要设置css:
<style lang="scss" scoped>
	page {
		height: 100vh;
		width: 100vw;
	}
</style>
-->

<template>
	<view style="position: relative; width: 100%; height: 100%; overflow: hidden; ">
		<!-- 表头 -->
		<scroll-view class="MyTable-scrollview" :style="_headerStyle">
			<view :style="'display: flex; position: relative; height: 100%; left:'+headerScrollLeft">
				<view v-for="(col, colidx) in columns" :key="colidx" style="height: 100%;">
					<view :style="'overflow: hidden; height: 100%; width:'+col.width" class="lay-c-c">{{col.name}}</view>
				</view>
			</view>
		</scroll-view>	
		
		<!-- 表体 -->
		<scroll-view class="MyTable-scrollview" :style="_bodyStyle" scroll-x scroll-y scroll-with-animation @scroll="onBodyScroll">
			<view v-for="(row, rowidx) in rows" :key="rowidx" :data-id="rowidx" :style="_rowStyle" @click="_onTapRow(rowidx)">
				<view v-for="(col, colidx) in columns" :key="colidx" style="height: 100%;" class="lay-c-c">
					<block v-if="col.btn">
						<block v-if="_isArray(row[colidx])">
							<view v-for="(item, itemidx) in row[colidx]" :style="'overflow: hidden; width:'+col.width" class="lay-sb-c-c">
								<button class="btn" @click.stop="_onTapBtn(rowidx, colidx, item)">{{item}}</button>
							</view>
						</block>
						<!-- @click后加.stop阻止冒泡，避免再触发onTapRow -->
						<button v-else  :style="'overflow: hidden; width:'+col.width" class="btn" @click.stop="_onTapBtn(rowidx, colidx, row[colidx])">{{row[colidx]}}</button>
					
					</block>
					
					<view v-else :style="'overflow: hidden; height: 100%; width:'+col.width" class="lay-c-c">{{row[colidx]}}</view>
				</view>
			</view>
		</scroll-view>
	</view>
</template>

<script>
	export default {
		name:"MyTable",
		data() {
			return { 
				headerScrollLeft:0,
			};
		},
		props: {
			columns: {
				type: Array,
				required: true,
				default: [
					{name: "column1", width: '200rpx'}, 
					{name: "column2", width: '200rpx'}]
			},
			rows: {
				type: Array,
				required: true,
				default: [["cell1-1", "cell1-2"],["cell2-1", "cell2-2"]]
			},
			headerHeight: { // 设置表头的高度
				type: String,
				required: false,
				default: "80rpx"
			},
			headerStyle: {
				type: Object,
				required: false,
				default: function() { // 对于Array和Object，默认值要用函数返回
					return {
						'background-color': '#FFF',	// 设置表头的背景色
					}
				}
			},
			bodyStyle: {
				type: Object,
				required: false,
				default: function() { // 对于Array和Object，默认值要用函数返回
					return {
						'background-color': '#FFF'
					}
				}
			},
			rowStyle: {
				type: Object,
				required: false,
				default: function() { // 对于Array和Object，默认值要用函数返回
					return {
						'height': '60rpx' // 行高
					}
				}
			},
			onTapRow: {
				type: Function,
				required: false,
				default: ()=>{}
			},
			onTapBtn: {
				type: Function,
				required: false,
				default: ()=>{}
			}
		},
		computed: {
			_headerStyle() {
				return this.bindStyle(Object.assign(this.headerStyle, {
					'position': 'absolute',
					'z-index': 1,
					'width': '100%',
					'height': this.headerHeight,	// 设置表头的高度
				}));
			},
			_bodyStyle() {
				return this.bindStyle(Object.assign(this.bodyStyle, {
					'height': '100%',
					'padding-top': this.headerHeight,
					'box-sizing': 'border-box' // fix: 上面设置padding-top后，整体高度就变了，导致部分内容看不到。border-box是css3特性，可控制margin，padding不影响盒子宽高。
				}));
			},
			_rowStyle() {
				let r = this.bindStyle(Object.assign(this.rowStyle, {
					'display': 'flex',
				}));
				// debugger
				return r;
			}
		},
		watch: {
			// 监听属性的变化。如果不监听，父组件更新属性后，子组件不会生变化
			columns(newVal, oldVal) { 
				this.columns = newVal;
			},
			rows(newVal, oldVal) {
				this.rows = newVal;
			}
		},
		methods: {
			bindStyle(style) {
				// #ifdef H5
				return style;
				// #endif
				// #ifndef H5
				let str = JSON.stringify(style);
				str = str.substr(1, str.length-2);
				str = str.replaceAll(",", ";");
				str = str.replaceAll("\"", "");
				return str;
				// #endif
			},
			
			// begin header和body两个scroll-view实现同步水平滚动
			onHeaderScroll(e) {
				// this.$nextTick(()=>{
				// 	this.bodyScrollLeft = e.detail.scrollLeft;
				// })
			},
			onBodyScroll(e) {
				this.headerScrollLeft = '-'+e.detail.scrollLeft+'px';
				//console.log("this.headerScrollLeft="+this.headerScrollLeft)
			},
			
			_onTapRow(rowidx) {
				this.onTapRow(rowidx);
			},
			
			_onTapBtn(rowidx, colidx, btnTitle) {
				this.onTapBtn(rowidx, colidx, btnTitle);
				// fix bug: vue子组件通过属性回调父组件方法时this指向子组件 （pages/fsh_race/race_score中有例子）
				this.$emit("tapBtnEvent", rowidx, colidx, btnTitle);
				// end
			},
			
			_isArray(a) {
				return a instanceof Array;
			}
		}
	}
</script>

<style lang="scss">
	@import "@/leui.scss";
	.MyTable-scrollview {
		white-space: nowrap;
		overflow: hidden;
	}
	
	/* scroll-view {
		background-color: white;
	} */
</style>
